package com.zhou.framework.domain;

import lombok.Data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author lang.zhou
 * @date 2019/6/3
 */
@Data
public class DomainOrg {

    /**
     * 组织结构名称
     */
    private String orgName;

    /**
     * 组织结构中文名称
     */
    private String chnName;
    /**
     * 下级名称
     */
    private List<DomainOrg> orgChildrenName=new ArrayList<>();

    public Map<String, String> getMapping() {
        return mapping;
    }

    public void setMapping(Map<String, String> mapping) {
        this.mapping = mapping;
    }

    /**
     * ou和组织中文名映射关系，根节点才有
     */
    private Map<String,String> mapping;

    public List<DomainOrg> getOrgChildrenName(){
        return orgChildrenName;
    }

    /**
     * 添加子部门
     */
    public void addChild(DomainOrg c){
        if(!ifHasSameChildren(this,c.orgName)){
            orgChildrenName.add(c);
        }
    }

    /**
     * 判断是否有子部门
     */
    public boolean hasChildren(){
        return orgChildrenName.size()>0;
    }


    public DomainOrg(){

    }
    public DomainOrg(String orgName){
        this.orgName=orgName;
    }
    public DomainOrg(String orgName, String chnName){
        this.orgName=orgName;
        this.chnName=chnName;
    }
    public void addObj2(String ouStr,Map<String,String> mapping){
        List<String> ous=getOU(ouStr);
        //List<Object[]> trash=new ArrayList<>();
        if(ous.size()==1){
            this.orgName=ous.get(0).replace("OU=","");
            this.chnName=mapping.get(this.orgName);
        }else{
            for(int i=ous.size()-1;i>0;i--){
                String p=ous.get(i).replace("OU=","");
                String c=ous.get(i-1).replace("OU=","");
                if(p.equals(orgName)){
                    this.addChild(new DomainOrg(c,mapping.get(c)));
                }else{
                    boolean res=addObject2(this,p,c,mapping);
                    //trash.add(new Object[]{p,c});

                }
            }
        }
        /*if(trash.size()>0){
            for(Object[] t : trash){

            }
        }*/
    }

    /**
     *
     * @param ouStr     distinguishedName
     */
    public void addObj1(String ouStr){
        List<String> ous=getOU(ouStr);
        //List<Object[]> trash=new ArrayList<>();
        if(ous.size()==1){
            this.orgName=ous.get(0).replace("OU=","");
        }else{
            for(int i=ous.size()-1;i>0;i--){
                String p=ous.get(i).replace("OU=","");
                String c=ous.get(i-1).replace("OU=","");
                if(p.equals(orgName)){
                    this.addChild(new DomainOrg(c));
                }else{
                    boolean res=addObject1(this,p,c);
                    //trash.add(new Object[]{p,c});

                }
            }
        }
        /*if(trash.size()>0){
            for(Object[] t : trash){

            }
        }*/
    }

    /**
     * 去掉distinguishedName中的dc，获得ou
     * @param ouStr     去掉distinguishedName中的dc
     */
    private List<String> getOU(String ouStr){
        //List<String> ous=Arrays.asList(ouStr.split(","));
        List<String> ous=new ArrayList<>();
        ous.addAll(Arrays.asList(ouStr.split(",")));
        for(int i=0;i<ous.size();i++){
            String obj=ous.get(i);
            if(obj == null || ! obj.startsWith("OU=")){
                ous.remove(obj);
                i--;
            }
        }
        return ous;
        //for(int i=ous.size())
    }

    /**
     * org中是否有和name同名的子节点
     */
    private boolean ifHasSameChildren(DomainOrg org, String name){
        for(DomainOrg o : org.orgChildrenName){
            if(o.getOrgName().equals(name)){
                return true;
            }
        }
        return false;
    }

    /**
     * 像节点里面添加一个元素
     * @param obj       节点
     * @param p         父节点名称
     * @param c         子节点名称
     * @param mapping   ou名和中文名的映射关系
     * @return          是否成功加入
     */
    public boolean addObject2(DomainOrg obj, String p, String c, Map<String,String> mapping){
        if(p.equals(obj.getOrgName())){
            obj.addChild(new DomainOrg(c,mapping.get(c)));
            return true;
        }else{
            for(DomainOrg org : obj.orgChildrenName){
                return addObject2(org,p,c,mapping);
            }
        }
        return false;
    }
    public boolean addObject1(DomainOrg obj, String p, String c){
        if(p.equals(obj.getOrgName())){
            obj.addChild(new DomainOrg(c));
            return true;
        }else{
            for(DomainOrg org : obj.orgChildrenName){
                return addObject1(org,p,c);
            }
        }
        return false;
    }

    /**
     * 得到搜索域用户时的ou层级关系
     * @param rot       根节点
     * @param orgName   ou的orgName
     * @param res       返回orgName带顺序的ou集合
     */
    public boolean getOu1(DomainOrg rot, String orgName, List<String> res){
        if(rot.getOrgName().equals(orgName)){
            res.add("OU="+orgName);
            return true;
        }else{
            res.add("OU="+rot.getOrgName());
            boolean success=false;
            for(DomainOrg d : rot.getOrgChildrenName()){
                success=getOu(d,orgName,res);
                if(success){
                    break;
                }
            }
            if(!success){
                res.remove("OU="+rot.getOrgName());
            }
            return success;
        }
    }
    public boolean getOu(DomainOrg rot, String orgName, List<String> res){
        /*if(DomainHelper.isChinese()){
            return getOu2(rot,orgName,res);
        }*/
        return getOu1(rot,orgName,res);
    }
    public boolean getOu2(DomainOrg rot, String orgName, List<String> res){
        if(rot.getChnName().equals(orgName)){
            res.add("OU="+orgName);
            return true;
        }else{
            res.add("OU="+rot.getChnName());
            boolean success=false;
            for(DomainOrg d : rot.getOrgChildrenName()){
                success=getOu2(d,orgName,res);
                if(success){
                    break;
                }
            }
            if(!success){
                res.remove("OU="+rot.getChnName());
            }
            return success;
        }
    }

}
